package com.itobase.questionnaire.service.impl;

import com.itobase.questionnaire.VO.PageDatas;
import com.itobase.questionnaire.VO.SurveyGroupVO;
import com.itobase.questionnaire.VO.UserVO;
import com.itobase.questionnaire.dto.GroupUpdateDTO;
import com.itobase.questionnaire.dto.SurveyGroupUpdateDTO;
import com.itobase.questionnaire.dto.UserDTO;
import com.itobase.questionnaire.exception.WrongParameterException;
import com.itobase.questionnaire.model.SendPool;
import com.itobase.questionnaire.model.Survey;
import com.itobase.questionnaire.model.SurveyGroup;
import com.itobase.questionnaire.model.auth.User;
import com.itobase.questionnaire.repository.*;
import com.itobase.questionnaire.service.ISurveyGroupService;
import com.itobase.questionnaire.template.Constant;
import com.itobase.questionnaire.util.ListUtil;
import com.itobase.questionnaire.util.PagingUtils;
import com.itobase.questionnaire.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.unbescape.css.CssIdentifierEscapeLevel;

import java.util.*;

import static org.springframework.data.mongodb.core.query.Criteria.where;

/**
 * @author: lphu
 * @create: 2018-09-02 15:06
 * @description:
 */

@Service
public class SurveyGroupService implements ISurveyGroupService
{
    @Autowired
    SurveyGroupRepository surveyGroupRepository;
    @Autowired
    UserRepository userRepository;
    @Autowired
    PersonGroupRepository personGroupRepository;
    @Autowired
    SurveyRepository surveyRepository;
    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    SendRepository sendRepository;
    @Autowired
    SubmitRepository submitRepository;
    @Autowired
    SurveyGroupService surveyGroupService;
    /**
     * 获取调查组列表
     * @return
     */
    public List<SurveyGroup> getSurveyGroupList()
    {
        return surveyGroupRepository.findAll(new Sort(Sort.Direction.DESC , "createTime"));
    }



    /**
     * 新建调查小组
     * @param surveyGroup
     */
    public void addGroup(SurveyGroup surveyGroup)
    {
        if (surveyGroup.getGroupName()=="")
            throw new WrongParameterException("调查组名不能为空");
        SurveyGroup oldSurveyGroup = surveyGroupRepository.findByGroupName(surveyGroup.getGroupName());
        if (oldSurveyGroup!=null)
            throw new WrongParameterException("调查组名重复");
        surveyGroupRepository.insert(surveyGroup);
    }

    /**
     * 根据调查组id获取用户
     * @param surveyGroupId
     * @param group
     * @return
     */
    public List<UserVO> getUsersBySurveyGroupId(String surveyGroupId, String group,String keyWord) {
        SurveyGroup surveyGroup = Optional.ofNullable(surveyGroupRepository.findOne(surveyGroupId))
                .orElseThrow(()->new WrongParameterException("传入参数错误"));
        List<UserVO> userVOList = new ArrayList<>();
        for (Map.Entry<String,List<String>> entry : surveyGroup.getGroup().entrySet())
        {
            if(entry.getValue()==null)
                continue;
            if(StringUtil.isEmpty(group)){
                for (String userId : entry.getValue()) {
                    User user = userRepository.findOne(userId);
                    UserVO userVO = new UserVO();
                    userVO.reconvert(user);
                    userVO.setUserType(personGroupRepository.findOne(user.getUserTypeId()).getGroupName());
                    userVO.setGroup(group);
                    userVOList.add(userVO);
                }
                ListUtil.removeDuplicateWithOrder(userVOList);
            }else {
                if (entry.getKey().equals(group)) {
                    for (String userId : entry.getValue()) {
                        User user = userRepository.findOne(userId);
                        UserVO userVO = new UserVO();
                        userVO.reconvert(user);
                        userVO.setUserType(personGroupRepository.findOne(user.getUserTypeId()).getGroupName());
                        userVO.setGroup(group);
                        userVOList.add(userVO);
                    }
                }
            }
        }
        return userVOList;
    }

    /**
     * 根据调查id获取人员信息
     * @param surveyId
     * @param group
     * @return
     */
    public PageDatas<UserVO> getUsersBySurveyId(Pageable pageable, String surveyId, String group,String keyWord) {
        Survey survey = Optional.ofNullable(surveyRepository.findOne(surveyId))
                .orElseThrow(()->new WrongParameterException("传入参数错误"));
        String surveyGroupID = Optional.ofNullable(survey.getSurveyGroupId())
                .orElseThrow(()->new WrongParameterException("该调查未绑定人员"));

        List<UserVO> userVOList = getUsers(surveyId,group,keyWord);
        //拿到数据后进行分页操作
        return PagingUtils.paging(pageable.getPageNumber(),userVOList,pageable.getPageSize());
    }

    /**
     * 往调查小组添加新用户
     * @param
     * @param
     */
    public void addUsers(UserDTO userDTO)
    {
        if(userDTO.getGroup()=="" || userDTO.getGroup()==null)
            throw new WrongParameterException("请选择调查组");
        //接受id group list
        SurveyGroup surveyGroup = surveyGroupRepository.findOne(userDTO.getSurveyGroupId());
        List<Survey> surveyList = surveyRepository.findBySurveyGroupId(surveyGroup.getId());
        List<User> bindUsers = new ArrayList<>();
        if(surveyList.size()!=0){
            bindUsers = surveyList.get(0).getUserList();
        }
        Optional.ofNullable(surveyGroup).orElseThrow(()->new WrongParameterException("参数错误"));
        //禁用
        if(userDTO.getUserIds().size()==0)
            throw new WrongParameterException("请选择用户传入");
        for (String id : userDTO.getUserIds())
        {
            Optional.ofNullable(userRepository.findOne(id))
                    .orElseThrow(()->new WrongParameterException("传入参数错误"));
            if (userRepository.findOne(id).getFlag()==false)
                throw new WrongParameterException("请不要选择被禁用的用户");
        }
        List<String> existedUser = new ArrayList<>();
        for(Map.Entry<String,List<String>> oldUserMap : surveyGroup.getGroup().entrySet())
        {
            User user;
            if (oldUserMap.getKey().equals(userDTO.getGroup()))
            {
                if(oldUserMap.getValue()==null) //空
                {
                    List<String> list = new ArrayList<>();
                    for (String newUserId : userDTO.getUserIds()) {
                        bindUsers.add(userRepository.findOne(newUserId));
                        list.add(newUserId);
                    }
                    oldUserMap.setValue(list);
                }else{ //非空
                    //验重
                    for (String newUserId : userDTO.getUserIds()) {
                        for (String oldUserId : oldUserMap.getValue()) {
                            if (oldUserId.equals(newUserId))
                                existedUser.add(newUserId);
                        }
                        bindUsers.add(userRepository.findOne(newUserId));
                        oldUserMap.getValue().add(newUserId);
                    }
                }
            }
        }
        if (existedUser.size()!=0)
        {
            StringBuilder stringBuilder = new StringBuilder();
            for (String existedId : existedUser)
                stringBuilder.append(userRepository.findOne(existedId).getName() + " ");
            throw new WrongParameterException("添加失败,"+stringBuilder + "已存在该组中,请重新添加");
        }
        if(surveyList.size()!=0){
            for (Survey survey : surveyList) {
                survey.setUserList(bindUsers);
            }
            surveyRepository.save(surveyList);
        }
        surveyGroupRepository.save(surveyGroup);
    }

    /**
     * 根据调查组id获取用户
     * @param surveyGroupId
     * @return
     */
    public List<String> getUsersById(String surveyGroupId)
    {
        List<String> userList = new ArrayList<>();
        Map<String,List<String>> group = Optional.ofNullable(surveyGroupRepository.findOne(surveyGroupId).getGroup())
                .orElseThrow(()->new WrongParameterException("传入参数错误"));
        for (Map.Entry<String,List<String>> entry : group.entrySet()) {
            List<String> userIds = entry.getValue();
            if (userIds != null) {
                for (int i = 0; i < userIds.size(); i++)
                    userList.add(userIds.get(i));
            }
        }
        return userList;
    }

    /**
     * 删除调查小组
     * @param surveyGroupId
     */
    public void deleteBySurveyGroupId(String surveyGroupId) {
        SurveyGroup oldSurveyGroup = Optional.ofNullable(surveyGroupRepository.findOne(surveyGroupId))
                .orElseThrow(()->new WrongParameterException("不存在该调查"));
        if (checkCanDelete(surveyGroupId))
            surveyGroupRepository.delete(oldSurveyGroup);
    }

    /**
     * 获取单个调查组
     * @param surveyGroupId
     * @return
     */
    public Map<String, List<String>> getGroupById(String surveyGroupId) {
        return surveyGroupRepository.findOne(surveyGroupId).getGroup();
    }

    /**
     * 删除用户
     * @param userDTO
     */
    public void deleteUsers(UserDTO userDTO)
    {
        SurveyGroup surveyGroup = Optional.ofNullable(surveyGroupRepository.findOne(userDTO.getSurveyGroupId()))
                .orElseThrow(()->new WrongParameterException("传入参数错误"));
        checkCanDelete(userDTO.getSurveyGroupId());
        List<Survey> surveyList = surveyRepository.findAll();
        for (Survey e : surveyList) {
            if (e.getSurveyGroupId() == null)
                continue;
            if (e.getSurveyGroupId().equals(userDTO.getSurveyGroupId()))
                throw new WrongParameterException("该调查组已绑定问卷,不能删除人员");
        }
        for(Map.Entry<String,List<String>> oldUsers : surveyGroup.getGroup().entrySet())
        {
            if (oldUsers.getKey().equals(userDTO.getGroup()))
            {
                for (String deleteUserId : userDTO.getUserIds())
                    oldUsers.getValue().remove(deleteUserId);
                break;
            }
        }
        surveyGroupRepository.save(surveyGroup);
    }

    /**
     * 增加评委构成组
     * @param surveyGroupId
     * @param group
     */
    public void addGroup(String surveyGroupId, String group) {
        if (group=="")
            throw new WrongParameterException("组名不能为空");
        SurveyGroup surveyGroup = Optional.ofNullable(surveyGroupRepository.findOne(surveyGroupId))
                .orElseThrow(()->new WrongParameterException("该调查小组不存在"));
        checkCanDelete(surveyGroupId);
        if (surveyGroup.getGroup()!=null) {
            for (Map.Entry<String, List<String>> entry : surveyGroup.getGroup().entrySet()) {
                if (group.equals(entry.getKey()))
                    throw new WrongParameterException("该类别组已存在");
            }
        }

        if (surveyGroup.getGroup()!=null){
            surveyGroup.getGroup().put(group,null);
        }else {
            Map<String,List<String>> map = new HashMap<>();
            map.put(group,null);
            surveyGroup.setGroup(map);
        }
        surveyGroupRepository.save(surveyGroup);
    }

    /**
     * 删除类别组
     * @param surveyGroupId
     * @param group
     */
    @Override
    public void deleteGroup(String surveyGroupId, String group) {
        SurveyGroup surveyGroup = surveyGroupRepository.findOne(surveyGroupId);
        Boolean flag = !checkCanDelete(surveyGroupId);
        for (Map.Entry<String,List<String>> entry : surveyGroup.getGroup().entrySet())
        {
            if(entry.getKey().equals(group))
                flag=true;
        }
        if(flag)
            surveyGroup.getGroup().remove(group);
        surveyGroupRepository.save(surveyGroup);
    }

    /**
     * 根据调查id 获取类别组
     * @param surveyGroupId
     * @return
     */
    public SurveyGroupVO getUsersBySurveyGroupId(String surveyGroupId) {
        SurveyGroupVO surveyGroupVO = new SurveyGroupVO();
        SurveyGroup surveyGroup = Optional.ofNullable(surveyGroupRepository.findOne(surveyGroupId))
                .orElseThrow(()->new WrongParameterException("传入参数错误"));
        Map<String,Integer> map  = new HashMap<>();
        for (Map.Entry<String,List<String>> entry : surveyGroup.getGroup().entrySet()) {
            if(entry.getValue()==null){
                map.put(entry.getKey(),0);
            }else {
                map.put(entry.getKey(), entry.getValue().size());
            }
        }
        surveyGroupVO.setSurveyGroupId(surveyGroup.getId());
        surveyGroupVO.setGroup(map);
        surveyGroupVO.setSurveyGroupName(surveyGroup.getGroupName());
        return surveyGroupVO;
    }

    /**
     * 补充人员
     * @param userDTO
     */
    public void addOtherUsers(UserDTO userDTO)
    {
        SurveyGroup surveyGroup = surveyGroupRepository.findOne(userDTO.getSurveyGroupId());
        Optional.ofNullable(surveyGroup).orElseThrow(()->new WrongParameterException("调查小组id错误"));
        List<String> oldUserId = surveyGroup.getGroup().get(Constant.OTHER_USERS);
        if(oldUserId==null)
        {
            surveyGroup.getGroup().put(Constant.OTHER_USERS,userDTO.getUserIds());
        }else{
            surveyGroup.getGroup().get(Constant.OTHER_USERS).addAll(userDTO.getUserIds());
        }
        surveyGroupRepository.save(surveyGroup);
    }

    /**
     * 修改调查组名字
     * @param surveyGroupUpdateDTO
     */
    @Override
    public void updateSurveyGroup(SurveyGroupUpdateDTO surveyGroupUpdateDTO)
    {
        if (surveyGroupUpdateDTO.getSurveyGroupName()=="")
            throw new WrongParameterException("调查组名不能为空");
        SurveyGroup oldSurveyGroup = surveyGroupRepository.findByGroupName(surveyGroupUpdateDTO.getSurveyGroupName());
        if (oldSurveyGroup!=null) {
            if (oldSurveyGroup.getId().equals(surveyGroupUpdateDTO.getSurveyGroupId()))
                throw new WrongParameterException("与之前调查组同名");
            else
                throw new WrongParameterException("已存在同名调查");
        }
        SurveyGroup nowSurveyGroup = Optional.ofNullable(surveyGroupRepository.findOne(surveyGroupUpdateDTO.getSurveyGroupId()))
                .orElseThrow(()->new WrongParameterException("传入id错误"));
        nowSurveyGroup.setGroupName(surveyGroupUpdateDTO.getSurveyGroupName());
        surveyGroupRepository.save(nowSurveyGroup);
    }

    /**
     * 修改类别组名字
     * @param groupUpdateDTO
     */
    @Override
    public void updateGroup(GroupUpdateDTO groupUpdateDTO)
    {
        if (groupUpdateDTO.getNewGroupName()=="")
            throw new WrongParameterException("类别组名字不能为空");
        SurveyGroup nowSurveyGroup = Optional.ofNullable(surveyGroupRepository.findOne(groupUpdateDTO.getSurveyGroupId()))
                .orElseThrow(()->new WrongParameterException("传入id错误"));
        Boolean flag = false;
        for (Map.Entry<String,List<String>> entry : nowSurveyGroup.getGroup().entrySet())
        {
            if (entry.getKey().equals(groupUpdateDTO.getNewGroupName()))
                throw new WrongParameterException("与其他类别组重复,请重新输入");
            if (entry.getKey().equals(groupUpdateDTO.getOldGroupName())) {
                flag = true;
            }
        }
        if (flag) {
            List<String> users = nowSurveyGroup.getGroup().get(groupUpdateDTO.getOldGroupName());
            nowSurveyGroup.getGroup().remove(groupUpdateDTO.getOldGroupName());
            nowSurveyGroup.getGroup().put(groupUpdateDTO.getNewGroupName(),users);
        }
        surveyGroupRepository.save(nowSurveyGroup);
    }

    /**
     * 判断用户是否已经被通知
     * @param userId
     * @return
     */
    public String checkInformed(String surveyId,String userId)
    {
        Survey survey = surveyRepository.findOne(surveyId);
        if(survey.getUserList_informed()==null)
            return Constant.DEFAULT_SEND;
        for (User user : survey.getUserList_informed())
        {
            if (user.getId().equals(userId))
                return Constant.SUCCESS_SEND;
        }
        return Constant.DEFAULT_SEND;
    }

    /**
     * 获取人员list
     * @param surveyId
     * @param group
     * @param keyWord
     * @return
     */
    public List<UserVO> getUsers(String surveyId,String group,String keyWord)
    {
        Survey survey = Optional.ofNullable(surveyRepository.findOne(surveyId))
                .orElseThrow(()->new WrongParameterException("传入参数错误"));
        List<UserVO> userVOList = new ArrayList<>();
        for (Map.Entry<String,List<String>> entry : surveyGroupRepository.findOne(survey.getSurveyGroupId()).getGroup().entrySet())
        {
            if(entry.getValue()==null || entry.getValue().size()==0)
                continue;
            //所有人员
            if(StringUtil.isEmpty(group)){
                if (StringUtil.isEmpty(keyWord))
                    userVOList.addAll(getUserVOByIds(entry.getValue(),group,surveyId));
                else
                    userVOList.addAll(getUserVOWithKeyWord(entry.getValue(),group,keyWord,surveyId));
            }else {
                //匹配到对应的group
                if (entry.getKey().equals(group)) {
                    if (StringUtil.isEmpty(keyWord))
                        userVOList.addAll(getUserVOByIds(entry.getValue(), group,surveyId));
                    else
                        userVOList.addAll(getUserVOWithKeyWord(entry.getValue(),group,keyWord,surveyId));
                    break;
                }
            }
        }
        ListUtil.removeDuplicateWithOrder(userVOList);
        return userVOList;
    }

    /**
     * 判断是否绑定调查
     * @param surveyGroupId
     * @return
     */
    private boolean checkCanDelete(String surveyGroupId)
    {
        List<Survey> surveyList = surveyRepository.findAll();
        for (Survey survey : surveyList)
        {
            if (survey.getSurveyGroupId()==null) {
                continue;
            } else {
                if (survey.getSurveyGroupId().equals(surveyGroupId))
                    throw new WrongParameterException("该人员组已绑定调查,不能删除");
            }
        }
        return true;
    }

    /**
     * 获得 userVOList对象
     * @param ids
     * @param group
     * @return
     */
    private List<UserVO> getUserVOByIds(List<String> ids,String group,String surveyId)
    {
        List<UserVO> userVOList = new ArrayList<>();
        Survey survey = new Survey();
        for (String userId : ids) {
            User user = userRepository.findOne(userId);
            survey = surveyRepository.findOne(surveyId);
            SendPool sendPool = new SendPool();
            sendPool = sendRepository.findByPhoneNumbrAndSurvey(user.getLongPhone(),survey.getTitle());
            UserVO userVO = new UserVO();
            userVO.reconvert(user);
            userVO.setUserType(personGroupRepository.findOne(user.getUserTypeId()).getGroupName());
            userVO.setGroup(group);
            if(submitRepository.findByUserIdAndSurveyId(userId,surveyId)==null){
                userVO.setFinished(Constant.TESTING);
            }else{
                userVO.setFinished(Constant.FINISHED);
            }
            if (sendPool == null) {
                userVO.setInformed("未通知");
            }else if(sendPool.getStatus().equals(Constant.INFORMING)){
                userVO.setInformed("待通知");
            }else{
                String count = sendPool.getNumber();
                if(count.equals("0")) {
                    userVO.setInformed("未通知");
                }else{
                    userVO.setInformed("已通知" + sendPool.getNumber() + "次");
                }
            }
            userVOList.add(userVO);
        }
        return userVOList;
    }

    /**
     * 获得 userVOList 对象
     * @param ids
     * @param group
     * @param keyWord
     * @param surveyId
     * @return
     */
    private List<UserVO> getUserVOWithKeyWord(List<String> ids,String group,String keyWord,String surveyId)
    {
        List<UserVO> userVOList_new = new ArrayList<>();
        List<UserVO> userVOList = getUserVOByIds(ids,group,surveyId);
        for(UserVO userVO:userVOList){
            if (userVO.getUsername().indexOf(keyWord)!=-1
                    || userVO.getCollegeName().indexOf(keyWord)!=-1
                    || userVO.getInformed().indexOf(keyWord)!=-1
                    || userVO.getLongPhone().indexOf(keyWord)!=-1
                    || userVO.getName().indexOf(keyWord)!=-1
                    || userVO.getUserType().indexOf(keyWord)!=-1
                    || userVO.getFinished().indexOf(keyWord)!=-1)
                userVOList_new.add(userVO);
            else{
                continue;
            }
        }
        return userVOList_new;
    }
}
